

import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.widgets.Canvas;





//abstract Robot class which all types of robots extend
public abstract class AbstractRobot implements Robot{
	
	 protected String name;
	
	 protected Position start,current; // starting and current positions.
	 protected int speed = 0,heading = 0;
	 protected int speedLimit;
	 protected int headingLimit;
	 
	 boolean hasFile = false;
	 String fileName;
	 
	 //constructor 
	 public AbstractRobot(){
		 start = new Position();
		 current = new Position();
	 }
	 
	 //sets speed and heading limits
	 public abstract void setLims();
	 //set starting position of robot
	 public void setStartingPosition(Position p) { start.set(p);}
	 //sets current position of robot
	 public void setCurrentPosition(Position p){ current.set(p);}
	 //returns robots speed limit
	 public int getSpeedLimit() {return speedLimit;}
	 //returns robots heading limit
	 public int getHeadingLimit() {return headingLimit;}
	 //returns direction in which robot is heading
	 public int getHeading() {return heading;}
	 //returns robots speed 
	 public int getSpeed() {return speed;}
	 //set robots speed
	 public void setSpeed(int speed) { this.speed = speed; }
	 //set robots heading
	 public void setHeading(int heading) { this.heading = heading; }
	 //gets robots type
	 public abstract String getType();

	 
	 //move robot = set its speed and direction according to limits
	 public void move(int speed, int deg) {
		 //set robot's speed
		 if(speed < -1 * speedLimit)
			 this.speed =  -1 * speedLimit;
		 else if(speedLimit < speed )
			 this.speed = speedLimit;
		 else
			 this.speed = speed;
			 
		 //set robot's direction
		 if(Math.abs(heading - deg) <= headingLimit)
			 this.heading = deg;
		 else if(deg > heading)
			 this.heading += headingLimit;
		 else
			 this.heading -= headingLimit;
	 }
	 
	 //act method - sets robot's current position to new position according to heading and speed
	 public void act() {
		 //get fixed heading
		 double a = fixHeading(heading);
		 //insert position according to calculations
		 int x = current.x + (int)Math.round(speed * Math.cos(a));
		 int y = current.y + (int)Math.round(speed * Math.sin(a));
		 current.set(x,y);
	 }
	 
	 //function converts "heading" angle to radians and fixes it's direction to match sin/cos funcs
	 protected double fixHeading(int hd)
	 {
		 /*we need to subtract the given angle from 360 since the direction is opposite,
		 then add 90 since 0 degrees is north. then change to radians*/
		 return ( ( (450 - hd) % 360 ) * Math.PI / 180 );
	 }
	 
	 //stop robot
	 public void stop() {
		 speed = 0;
	 }
	 
	 //get robot's current position
	 public Position getCurrentPosition() {
		 return current;
	 }

	 //returns distance from starting point to current point
	 public long getDistance(){
		 //( (x2 - x1)^2 + (y2 - y1)^2 ) ^ 0.5 )
		 return Math.round((Math.sqrt(Math.pow(current.x - start.x, 2) + Math.pow(current.y - start.y,2))));
	}
	 
	//returns robot's name
	public String getName() {return name;}
	//return robot's fileName
	public String getFileName() {return fileName;}
	
	//compare to another robot according to name
	public int compareTo(Robot other){
		return name.compareTo(other.getName());
	}

	//returns true if picked up box and false if didn't
	public boolean pickupBox(Box box){ return false; }
	//returns true if put down box and false if didn't
	public boolean putdownBox() {return false;}
	//return state of robot's hasFile
	public boolean hasFile() { return hasFile; }
	//sets robot hasFile state
	public void setHasFile(boolean bool)  { hasFile = bool; }
	//set file name
	public void setFileName(String fileName){
		//if doesn't already have file
		if(!hasFile())
			this.fileName = fileName; 
		else
			System.out.println("can't set file - has one already");
	}
	
	
	public void paint(PaintEvent e){
		Canvas c = (Canvas)e.widget; // get the canvas
		int maxX = c.getSize().x;	 // max size
		int maxY = c.getSize().y;
		
		int mx = maxX/2,my = maxY/2;// mid point as (0,0)
		int myX = mx + current.x;	// set the current position
		int myY = my - current.y;	// set the current position
			
		e.gc.drawOval(myX-10, myY-10, 20, 20);	// the circle
		
		
		//calculate end point of line
		double alpha = fixHeading(heading);
		int x2 = (int)Math.round(myX + 30 * Math.cos(alpha)); 
		int y2 = (int)Math.round(myY - 30 * Math.sin(alpha));
		
		e.gc.drawLine(myX, myY, x2, y2);  
		
		// the info
		e.gc.drawString(name, myX+13, myY-13,true);
		e.gc.drawString(getType(), myX+13, myY, true);
		e.gc.drawString("("+current.x+","+current.y+")",myX+13, myY+13,true);
	}

}
